Add Group Sequential Design and Bayes Factor (Sequential) Design#87
Add Group Sequential Design and Bayes Factor (Sequential) Design#87FBartos wants to merge 24 commits into
Conversation
Introduce a new Evidence analysis: export Evidence in NAMESPACE; add a stub R handler R/Evidence.R that creates an interface panel with a placeholder message (calculations to be implemented later); register the analysis in inst/Description.qml; and add the full UI definition inst/qml/Evidence.qml (QML form with parameters, priors, design options, plots, and advanced settings).
Replace placeholder Evidence interface with a full implementation: R/Evidence.R now prepares settings, computes evidence probabilities and sample-size searches, builds results/prior/design tables, explanatory HTML, and multiple plots (by N, effect size, and priors). Uses bfpwr for core Bayesian calculations and includes robust error handling and plotting via ggplot2/jaspGraphs. DESCRIPTION updated to import and reference the SamCH93/bfpwr package. UI/QML updated to add a Bayesian group and include a new powerBayes SVG icon (inst/icons/powerBayes.svg) for the Evidence analysis.
|
👋 Friendly reminder: It looks like If your changes include bug fixes, new features, or UI tweaks, please consider adding a quick note to the |
|
build builder bot, build for glory! |
✅ Build Complete!Your JASP module bundles have been successfully built for macOS (ARM) and Windows. 👉 Click here to download the artifacts (Scroll to the bottom of the page to find the "Artifacts" section). |
…ntain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
| Form | ||
| { | ||
| info: qsTr("Bayes Factor sequential design allows you to design sequential experiments for conclusive evidence.\n\n" + | ||
| "See [this tutorial](TODO) for a detailed introduction to the module.") |
There was a problem hiding this comment.
lets comment this line out for now, and put it back in once the tutorial is preprinted
| Form | ||
| { | ||
| info: qsTr("Bayes Factor design allows you to design fixed sample size experiments for conclusive evidence.\n\n" + | ||
| "See [this tutorial](TODO) for a detailed introduction to the module.") |
| if (settings[["isIndependentSamples"]] && settings[["sampleSizeRatio"]] != 1) | ||
| stop(gettext("Sample-size search for unequal group sizes is handled internally.")) | ||
|
|
||
| if (settings[["drangeMode"]] == "custom") | ||
| stop(gettext("Sample-size search for custom t search ranges is handled internally.")) | ||
|
|
||
| if (!isTRUE(all.equal(settings[["nullValue"]], 0))) | ||
| stop(gettext("Sample-size search for nonzero null values is handled internally.")) |
There was a problem hiding this comment.
Are these errors meant for users? When/ how can they occur? If they occur only when an analyst has done something wrong, they shouldn't be translated so no gettext. Please add a comment describing what these errors are for.
There was a problem hiding this comment.
these errors looks odd and should be never reached
| .bfdReportTestLabel <- function(settings) { | ||
| .bfdRequireKnownOption(gettext("test"), settings[["test"]], .bfdKnownTests) | ||
|
|
||
| switch(settings[["test"]], |
There was a problem hiding this comment.
Same switch statement as .bfdTestLabel, avoid duplication.
| .bfdPriorSpikeRow <- function(x, prior, height) { | ||
| return(data.frame( | ||
| x = x, | ||
| height = height, | ||
| prior = prior, | ||
| stringsAsFactors = FALSE | ||
| )) | ||
| } | ||
|
|
||
| .bfdPriorSpikeRows <- function(rows) { | ||
| if (length(rows) == 0) { | ||
| return(data.frame( | ||
| x = numeric(0), | ||
| height = numeric(0), | ||
| prior = character(0), | ||
| stringsAsFactors = FALSE | ||
| )) | ||
| } | ||
|
|
||
| return(do.call(rbind, rows)) | ||
| } |
There was a problem hiding this comment.
| .bfdPriorSpikeRow <- function(x, prior, height) { | |
| return(data.frame( | |
| x = x, | |
| height = height, | |
| prior = prior, | |
| stringsAsFactors = FALSE | |
| )) | |
| } | |
| .bfdPriorSpikeRows <- function(rows) { | |
| if (length(rows) == 0) { | |
| return(data.frame( | |
| x = numeric(0), | |
| height = numeric(0), | |
| prior = character(0), | |
| stringsAsFactors = FALSE | |
| )) | |
| } | |
| return(do.call(rbind, rows)) | |
| } | |
| .bfdPriorSpikeRow <- function(x, prior, height) { | |
| return(data.frame( | |
| x = x, | |
| height = height, | |
| prior = prior, | |
| stringsAsFactors = FALSE | |
| )) | |
| } | |
| .bfdPriorSpikeRows <- function(rows) { | |
| if (length(rows) == 0) { | |
| return(.bfdPriorSpikeRow(numeric(), numeric(), character())) | |
| } | |
| return(do.call(rbind, rows)) | |
| } |
There was a problem hiding this comment.
too much duplication again
| isZTest = grepl("ZTest", test, fixed = TRUE) || identical(test, "generalZApproximation"), | ||
| isBinomial = FALSE, | ||
| calculation = options[["calculationTarget"]], | ||
| bf10Threshold = options[["conclusiveEvidenceThresholdH1"]], |
There was a problem hiding this comment.
This is confusion and renames some options. Why not just add options as a whole to the settings? That way someone can understand which name maps onto which option in QML.
| .bfdCreatePlot <- function(parent, key, title, position, dependencies, width, height) { | ||
| if (!is.null(parent[[key]])) | ||
| return(NULL) | ||
|
|
||
| plot <- createJaspPlot(title = title, width = width, height = height) | ||
| plot$dependOn(dependencies) | ||
| plot$position <- position | ||
| parent[[key]] <- plot | ||
|
|
||
| return(plot) | ||
| } |
There was a problem hiding this comment.
This feels overengineered.
| .bfdCachedPlotData <- function(jaspResults, stateKey, dependencies, dataKey, compute) { | ||
| state <- jaspResults[[stateKey]] | ||
| if (is.null(state)) { | ||
| state <- createJaspState() | ||
| state$dependOn(dependencies) | ||
| jaspResults[[stateKey]] <- state | ||
| } | ||
|
|
||
| cache <- state$object | ||
| if (is.null(cache)) | ||
| cache <- list() | ||
|
|
||
| if (!is.null(cache[[dataKey]])) | ||
| return(cache[[dataKey]]) | ||
|
|
||
| cache[[dataKey]] <- try(compute(), silent = TRUE) | ||
| state$object <- cache | ||
|
|
||
| return(cache[[dataKey]]) | ||
| } |
There was a problem hiding this comment.
This reimplements %setOrRetrieve%, no? See https://github.com/jasp-stats/jaspBase/blob/master/R/setOrRetrieve.R
| html <- .bfdCreateHtml( | ||
| parent = parent, | ||
| key = key, | ||
| title = title, | ||
| position = position, | ||
| dependencies = dependencies | ||
| ) |
There was a problem hiding this comment.
bfdCreateHtml is likely also overengineered
| testType = testType, | ||
| designTypeLabel = .csdDesignTypeLabel(options[["designType"]]), | ||
| numberOfLooks = options[["numberOfLooks"]], | ||
| timingMode = options[["timingMode"]], |
There was a problem hiding this comment.
same remark as before, just append options.
adds the following analyses: